package com.qiantu.phone.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SweepGradient;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.animation.LinearInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.qiantu.phone.R;
import com.qiantu.phone.app.AppApplication;

/**
 * @ClassName RoundSeekBar
 * @Description TODO
 * @Author ShiJunqiang
 * @Date 2021/5/21 16:54
 * @Version 1.0
 */
public class FreshAirSwitchView extends View {
    /**
     * 圆环笔画的宽度
     */
    private float mBigStrokeWidth;
    private float mSmallStrokeWidth;
    private String value;
    //默认温度
    private String defaultValue = "--";
    private Drawable centerOnDrawable;
    private Drawable centerOffDrawable;
    private Drawable gradientCircleDrawable;
    private SweepGradient mGradient;
    private Paint mPaint;
    private TextPaint mTextPaint;
    private int bigTextSize;
    private int unitAndLabelTextSize;
    private String labelText;
//    private String unitText = "μg/m3";
    private String unitText;
    private int percentage_unit_padding;
    private int percentage_label_padding;
    private boolean isOpen = false;
    private int[] gradientColors = new int[]{0xFF3F8AFE, 0xFF54ABF9, 0xFF72C9FB, 0xFF7AE1FA, 0x6694DBE2, 0x3394DBE2, 0x26DCF2F7};
    private float[] gradientPositions = new float[]{0, 0.25f, 0.5f, 0.65f, 0.85f, 0.95f, 1};
    private Matrix matrix;
    //开关范围
    private Rect switchRect;
    private int switchClickPadding;
    private boolean isSwitchDown;
    //风速是否设置
    private boolean windSpeedIsNotSet;
    private float outRingPadding;
    private float inRingPadding;
    private float centerCircleShadowWidth;
    private float rotationDegree;
    private String windSpeedText;
    private String closeText;
    private boolean hasAnimation = true;
    private boolean hasValue = true;
    private float centerRadius;
    private int deviceSolidBgColor;

    public FreshAirSwitchView(Context context) {
        this(context, null);
    }

    public FreshAirSwitchView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FreshAirSwitchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public FreshAirSwitchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(AppApplication.getInstance().getThemeColor(R.attr.textColor1));
        mBigStrokeWidth = getResources().getDimensionPixelSize(R.dimen.dp_16);
        mSmallStrokeWidth = getResources().getDimensionPixelSize(R.dimen.dp_3);
        centerOnDrawable = AppApplication.getInstance().getThemeDrawable(R.attr.icon_devicecontrol_curtain_switch_5);
        centerOffDrawable = AppApplication.getInstance().getThemeDrawable(R.attr.icon_devicecontrol_curtain_switch_2);
        gradientCircleDrawable = AppApplication.getInstance().getThemeDrawable(R.attr.icon_devicecontrol_freshair);
        bigTextSize = getResources().getDimensionPixelSize(R.dimen.dp_20);
        unitAndLabelTextSize = getResources().getDimensionPixelSize(R.dimen.dp_12);
        percentage_unit_padding = getResources().getDimensionPixelSize(R.dimen.dp_4);
        percentage_label_padding = getResources().getDimensionPixelSize(R.dimen.dp_8);
        outRingPadding = getResources().getDimensionPixelSize(R.dimen.dp_29);
        inRingPadding = getResources().getDimensionPixelSize(R.dimen.dp_36);
        centerCircleShadowWidth = getResources().getDimensionPixelSize(R.dimen.dp_52);
        matrix = new Matrix();
        switchRect = new Rect();
        switchClickPadding = getResources().getDimensionPixelSize(R.dimen.dp_10);
        closeText = getResources().getString(R.string.close);
        value = defaultValue;
        windSpeedText = defaultValue;
        deviceSolidBgColor = AppApplication.getInstance().getThemeColor(R.attr.deviceSolidBgColor);
    }

    public void setHasAnimation(boolean hasAnimation) {
        this.hasAnimation = hasAnimation;
        invalidate();
    }

    public void setHasValue(boolean hasValue) {
        this.hasValue = hasValue;
        invalidate();
    }

    public void setSpeedName(String windSpeedName) {
        if (TextUtils.isEmpty(windSpeedName)) {
            windSpeedIsNotSet = true;//未设置
        } else {
            windSpeedIsNotSet = false;
        }
        if(windSpeedName == null){
            windSpeedText = "";
        }else{
            windSpeedText = windSpeedName;
        }
        invalidate();
    }

    public void setDefaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int defaultValue = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics());
        int width = measureHandler(widthMeasureSpec, defaultValue);
        int height = measureHandler(heightMeasureSpec, defaultValue);
        setMeasuredDimension(Math.min(width, height), Math.min(width, height));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    /**
     * 测量
     *
     * @param measureSpec
     * @param defaultSize
     * @return
     */
    private int measureHandler(int measureSpec, int defaultSize) {
        int result = defaultSize;
        int measureMode = MeasureSpec.getMode(measureSpec);
        int measureSize = MeasureSpec.getSize(measureSpec);
        if (measureMode == MeasureSpec.EXACTLY) {
            result = measureSize;
        } else if (measureMode == MeasureSpec.AT_MOST) {
            result = Math.min(defaultSize, measureSize);
        }
        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawArc(canvas);
    }

    private void drawArc(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        int centerX = width / 2;
        int centerY = height / 2;
        int radius = Math.min(centerX, centerY);
        centerRadius = radius - centerCircleShadowWidth;
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mSmallStrokeWidth);
        mPaint.setColor(0x59e1e5e8);
        canvas.drawCircle(centerX, centerY, radius - outRingPadding - mSmallStrokeWidth / 2f, mPaint);

        int bottom = (int) (centerY + radius - getResources().getDimensionPixelSize(R.dimen.dp_11) - inRingPadding - mBigStrokeWidth);
        switchRect.bottom = bottom;
        Paint.FontMetricsInt fontMetricsInt = null;
        if (!isOpen) {//关闭状态
            stop();
            labelText = closeText;
            rotationDegree = 0;
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBigStrokeWidth);
            mPaint.setColor(0xffe5e8eb);
            canvas.drawCircle(centerX, centerY, radius - inRingPadding - mBigStrokeWidth / 2f, mPaint);

            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(deviceSolidBgColor);
            mPaint.setShadowLayer(centerCircleShadowWidth, 0, getResources().getDimensionPixelSize(R.dimen.dp_26), 0x0f25334b);
            canvas.drawCircle(centerX, centerY, centerRadius, mPaint);

            mPaint.setShadowLayer(getResources().getDimensionPixelSize(R.dimen.dp_26), 0, getResources().getDimensionPixelSize(R.dimen.dp_11), 0x1425334B);
            canvas.drawCircle(centerX, centerY, radius - centerCircleShadowWidth, mPaint);

            mPaint.setShadowLayer(getResources().getDimensionPixelSize(R.dimen.dp_13), 0, getResources().getDimensionPixelSize(R.dimen.dp_4), 0x0525334b);
            canvas.drawCircle(centerX, centerY, radius - centerCircleShadowWidth, mPaint);
            mPaint.clearShadowLayer();

            if (centerOffDrawable != null) {
                switchRect.left = radius - centerOffDrawable.getIntrinsicWidth() / 2;
                switchRect.top = bottom - centerOffDrawable.getIntrinsicHeight();
                switchRect.right = radius + centerOffDrawable.getIntrinsicWidth() / 2;
                switchRect.bottom = bottom;
                centerOffDrawable.setBounds(switchRect);
                centerOffDrawable.draw(canvas);
            }
        } else {
            labelText = windSpeedText;
//            mPaint.setColor(0xffffffff);
//            mPaint.setStyle(Paint.Style.STROKE);
//            mPaint.setStrokeWidth(mBigStrokeWidth);
//            if (mGradient == null) {
//                mGradient = new SweepGradient(centerX, centerY, gradientColors, gradientPositions);
//                matrix.setRotate(270, centerX, centerX);
//                mGradient.setLocalMatrix(matrix);
//            }
//            mPaint.setShader(mGradient);
            if(hasAnimation){
                start();
                canvas.save();
                canvas.rotate(-rotationDegree, centerX, centerY);
//                canvas.drawCircle(centerX, centerY, radius - inRingPadding - mBigStrokeWidth / 2f, mPaint);
//                mPaint.setShader(null);
//                mPaint.setColor(gradientColors[0]);
//                mPaint.setStyle(Paint.Style.FILL);
//                canvas.drawCircle(centerX, inRingPadding + mBigStrokeWidth / 2f, mBigStrokeWidth / 2f, mPaint);
                gradientCircleDrawable.setBounds((int)inRingPadding, (int)inRingPadding, (int)(width - inRingPadding), (int)(height - inRingPadding));
                gradientCircleDrawable.draw(canvas);
                canvas.restore();
            }else {
//                canvas.drawCircle(centerX, centerY, radius - inRingPadding - mBigStrokeWidth / 2f, mPaint);
//                mPaint.setShader(null);
//                mPaint.setColor(gradientColors[0]);
//                mPaint.setStyle(Paint.Style.FILL);
//                canvas.drawCircle(centerX, inRingPadding + mBigStrokeWidth / 2f, mBigStrokeWidth / 2f, mPaint);
                gradientCircleDrawable.setBounds((int)inRingPadding, (int)inRingPadding, (int)(width - inRingPadding), (int)(height - inRingPadding));
                gradientCircleDrawable.draw(canvas);
            }
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(deviceSolidBgColor);
            mPaint.setShadowLayer(getResources().getDimensionPixelSize(R.dimen.dp_4), 0, getResources().getDimensionPixelSize(R.dimen.dp_2), AppApplication.getInstance().getThemeColor(R.attr.freshAirRingShadowColor));
            canvas.drawCircle(centerX, centerY, radius - centerCircleShadowWidth, mPaint);
            mPaint.clearShadowLayer();

            if (centerOnDrawable != null) {
                switchRect.left = radius - centerOnDrawable.getIntrinsicWidth() / 2;
                switchRect.top = bottom - centerOnDrawable.getIntrinsicHeight();
                switchRect.right = radius + centerOnDrawable.getIntrinsicWidth() / 2;
                switchRect.bottom = bottom;
                centerOnDrawable.setBounds(switchRect);
                centerOnDrawable.draw(canvas);
            }
        }

        String text;
        mTextPaint.setTextSize(unitAndLabelTextSize);
        fontMetricsInt = mTextPaint.getFontMetricsInt();
        int unitAndLabelTextHeight = fontMetricsInt.descent - fontMetricsInt.ascent;
        int bottomTextHeight = 0;
        if (windSpeedIsNotSet) {
            text = getResources().getString(R.string.not_set);
            mTextPaint.setTextSize(bigTextSize);
            float percentageTextWidth = mTextPaint.measureText(text);
            Paint.FontMetricsInt percentageTexFontMetricsInt = mTextPaint.getFontMetricsInt();
            bottomTextHeight = percentageTexFontMetricsInt.descent - percentageTexFontMetricsInt.ascent;
            float percentageTextY = centerY + bottomTextHeight / 2 - percentageTexFontMetricsInt.descent;
            float percentageX = centerX - percentageTextWidth / 2;
            canvas.drawText(text, percentageX, percentageTextY, mTextPaint);
        } else {
            if(hasValue) {
                float unitTextWidth = 0;
                boolean needPaintUnitText = false;
                int percentageUnitPadding = 0;
                if(!TextUtils.isEmpty(unitText)){
                    unitTextWidth = mTextPaint.measureText(unitText);
                    needPaintUnitText = true;
                    percentageUnitPadding = percentage_unit_padding;
                }
                mTextPaint.setTextSize(bigTextSize);
                mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
                float percentageTextWidth = mTextPaint.measureText(value);
                Paint.FontMetricsInt percentageTexFontMetricsInt = mTextPaint.getFontMetricsInt();
                bottomTextHeight = percentageTexFontMetricsInt.descent - percentageTexFontMetricsInt.ascent;
                float percentageTextY = centerY + bottomTextHeight / 2 - percentageTexFontMetricsInt.descent;
                float percentageX = centerX - (percentageTextWidth + percentageUnitPadding + unitTextWidth) / 2;
                mTextPaint.setTextSize(bigTextSize);
                mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
                canvas.drawText(value, percentageX, percentageTextY, mTextPaint);
                if(needPaintUnitText){
                    float unitTextY = centerY + unitAndLabelTextHeight / 2 - fontMetricsInt.descent + (bottomTextHeight - unitAndLabelTextHeight) / 4;
                    mTextPaint.setTextSize(unitAndLabelTextSize);
                    mTextPaint.setTypeface(Typeface.DEFAULT);
                    canvas.drawText(unitText, percentageX + percentageTextWidth + percentageUnitPadding, unitTextY, mTextPaint);
                }

                mTextPaint.setTextSize(unitAndLabelTextSize);
                mTextPaint.setTypeface(Typeface.DEFAULT);
                float labelTextWidth = mTextPaint.measureText(labelText);
                fontMetricsInt = mTextPaint.getFontMetricsInt();
                float labelTextY = centerY + unitAndLabelTextHeight / 2 - fontMetricsInt.descent - (percentage_label_padding + bottomTextHeight / 2);
                canvas.drawText(labelText, centerX - labelTextWidth / 2, labelTextY, mTextPaint);
            }else{
                mTextPaint.setTextSize(bigTextSize);
                mTextPaint.setTypeface(Typeface.DEFAULT);
                fontMetricsInt = mTextPaint.getFontMetricsInt();
                float labelTextWidth = mTextPaint.measureText(labelText);
                float labelTextHeight = fontMetricsInt.descent - fontMetricsInt.ascent;
                float labelTextY = centerY + labelTextHeight / 2 - fontMetricsInt.descent;
                canvas.drawText(labelText, centerX - labelTextWidth / 2, labelTextY, mTextPaint);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isEnabled()) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    float downX = event.getX();
                    float downY = event.getY();
                    //开关点击范围
                    isSwitchDown = isInSwitchArea(downX, downY);
                    break;
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP:
                    float upX = event.getX();
                    float upY = event.getY();
                    //点击开关按钮
                    if (isSwitchDown && isInSwitchArea(upX, upY)) {
                        isOpen = !isOpen;
                        //如果打开，并且value是空，那么就设置默认
                        if (isOpen && TextUtils.isEmpty(value)) {
                            value = defaultValue;
                        }
                        if(!isOpen){
                            //关闭状态显示关闭文字 不显示未设置
                            windSpeedIsNotSet = false;
                        }else{
                            if(TextUtils.isEmpty(windSpeedText)){
                                windSpeedIsNotSet = true;//未设置
                            }else{
                                windSpeedIsNotSet = false;//已设置
                            }
                        }
                        invalidate();
                        if (mOnChangeListener != null) {
                            playSoundEffect(SoundEffectConstants.CLICK);
                            mOnChangeListener.onSwitch(isOpen);
                        }
                    }
                    isSwitchDown = false;
                    break;
                case MotionEvent.ACTION_CANCEL:
                    isSwitchDown = false;
                    break;
            }
        }
        return true;
    }


    private boolean isInSwitchArea(float x, float y) {
//        //点击开关图标
//        return (switchRect.left - switchClickPadding <= x && x <= switchRect.right + switchClickPadding)
//                && (switchRect.top - switchClickPadding <= y && y <= switchRect.bottom + switchClickPadding);
        float centerX = getWidth() / 2;
        float centerY = getHeight() / 2;
        float clickDistance = (float) Math.sqrt(Math.pow(Math.abs(x - centerX), 2) + Math.pow(Math.abs(y - centerY), 2));
        return clickDistance < centerRadius;
    }

    public void setOpenState(boolean openState) {
        if (isOpen == openState) {
            return;
        }
//        if (openState) {
//            mTemp = preTemp;
//        } else {
//            preTemp = mTemp;
//        }
        isOpen = openState;
//        calculateProgressByTemp();
        invalidate();
    }

    public boolean isOpen() {
        return isOpen;
    }

    public void setValue(String value) {
//        if (TextUtils.isEmpty(value)) {
//            tempIsNotSet = true;//未设置
//        } else {
//            tempIsNotSet = false;
//        }
        this.value = value;
        invalidate();
    }

    public void setUnitText(String unitText) {
        this.unitText = unitText;
    }

    private OnChangeListener mOnChangeListener;

    public void setOnChangeListener(OnChangeListener mOnChangeListener) {
        this.mOnChangeListener = mOnChangeListener;
    }

    public interface OnChangeListener {
        void onSwitch(boolean isOpen);
    }

    private ValueAnimator.AnimatorUpdateListener mUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            rotationDegree = (int) animation.getAnimatedValue();
            invalidate();
        }
    };

    ValueAnimator mAnimator = null;

    public void start() {
        if (mAnimator == null) {
            mAnimator = ValueAnimator.ofInt(0, 359);
            mAnimator.addUpdateListener(mUpdateListener);
            mAnimator.setDuration(1400);
            mAnimator.setRepeatMode(ValueAnimator.RESTART);
            mAnimator.setRepeatCount(ValueAnimator.INFINITE);
            mAnimator.setInterpolator(new LinearInterpolator());
            mAnimator.start();
        } else if (!mAnimator.isStarted()) {
            mAnimator.start();
        }
    }

    public void stop() {
        if (mAnimator != null) {
            mAnimator.removeUpdateListener(mUpdateListener);
            mAnimator.removeAllUpdateListeners();
            mAnimator.cancel();
            mAnimator = null;
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        start();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stop();
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == VISIBLE) {
            start();
        } else {
            stop();
        }
    }
}
